package orderMap

type OrderMap struct {
	idxToKey   []interface{}
	keyToIdx   map[interface{}]int
	keyToValue map[interface{}]interface{}
}

func NewOrderMap() *OrderMap {
	o := &OrderMap{
		idxToKey:   []interface{}{},
		keyToIdx:   map[interface{}]int{},
		keyToValue: map[interface{}]interface{}{},
	}
	return o
}

func (this *OrderMap) Add(key, val interface{}) {

	this.keyToValue[key] = val

	this.keyToIdx[key] = len(this.idxToKey)
	this.idxToKey = append(this.idxToKey, key)
}

func (this *OrderMap) Del(key interface{}) {
	idx, ok := this.keyToIdx[key]
	if ok {
		this.idxToKey = append(this.idxToKey[:idx], this.idxToKey[idx+1:]...)
		delete(this.keyToValue, key)

		this.keyToIdx = map[interface{}]int{}
		for i, k := range this.idxToKey {
			this.keyToIdx[k] = i
		}
	}
}

func (this *OrderMap) Len() int {
	return len(this.keyToValue)
}

func (this *OrderMap) GetValueByIdx(idx int) interface{} {
	if idx < 0 || idx >= len(this.idxToKey) {
		return nil
	}

	return this.keyToValue[this.idxToKey[idx]]
}

func (this *OrderMap) GetValueByKey(key interface{}) interface{} {
	val, ok := this.keyToValue[key]
	if !ok {
		return nil
	} else {
		return val
	}

}

func (this *OrderMap) Sort() {

}

func (this *OrderMap) RandomRead() []interface{} {
	ret := []interface{}{}
	for _, v := range this.keyToValue {
		ret = append(ret, v)
	}
	return ret
}

func (this *OrderMap) OrderRead() []interface{} {
	ret := []interface{}{}
	for _, v := range this.idxToKey {
		ret = append(ret, this.keyToValue[v])
	}
	return ret
}

func (this *OrderMap) RandOneKey() interface{} {
	if len(this.idxToKey) == 0 {
		return nil
	}
	return this.idxToKey[0]
}
